package com.teaching.teachingsupport.service.impl.teacherserviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teaching.teachingsupport.common.enums.HomeworkStatus;
import com.teaching.teachingsupport.common.pojo.dataobject.*;
import com.teaching.teachingsupport.common.pojo.dto.request.CreateHomeworkRequest;
import com.teaching.teachingsupport.common.pojo.dto.request.HomeworkQuestionRequest;
import com.teaching.teachingsupport.common.pojo.dto.response.CourseResponse;
import com.teaching.teachingsupport.common.pojo.dto.response.HomeworkListResponse;
import com.teaching.teachingsupport.common.pojo.dto.response.TeachingClassResponse;
import com.teaching.teachingsupport.common.pojo.dto.response.HomeworkScoreDetailResponse;
import com.teaching.teachingsupport.common.exception.BusinessException;
import com.teaching.teachingsupport.common.constant.FilePathConstants;
import com.teaching.teachingsupport.common.utils.SecurityUtils;
import com.teaching.teachingsupport.mapper.HomeworkSubmissionMapper;
import com.teaching.teachingsupport.mapper.studentviewmapper.CourseMapper;
import com.teaching.teachingsupport.mapper.teacherviewmapper.*;
import com.teaching.teachingsupport.service.service2.teacherservice.TeacherHomeworkService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Optional;

import com.teaching.teachingsupport.common.pojo.dataobject.HomeworkAttachment;
import com.teaching.teachingsupport.mapper.teacherviewmapper.HomeworkAttachmentMapper;
import com.teaching.teachingsupport.mapper.teacherviewmapper.QuestionSubmissionMapper;

@Service
@RequiredArgsConstructor
public class TeacherHomeworkServiceImpl implements TeacherHomeworkService {

    private final SecurityUtils securityUtils;
    private final TeacherCourseMapper teacherCourseMapper;
    private final CourseMapper courseMapper;
    private final TeacherHomeworkMapper teacherHomeworkMapper;
    private final HomeworkSubmissionMapper homeworkSubmissionMapper;
    private final TeachingClassMapper teachingClassMapper;
    private final HomeworkQuestionMapper homeworkQuestionMapper;
    private final HomeworkStudentMapper homeworkStudentMapper;
    private final HomeworkAttachmentMapper homeworkAttachmentMapper;
    private final QuestionSubmissionMapper questionSubmissionMapper;

    @Override
    @Transactional
    public Long createHomework(CreateHomeworkRequest request, MultipartFile attachment) {
        // 获取当前教师ID
        Long teacherId = securityUtils.getCurrentUserId();
        
        // 根据课程名称和教师ID查找课程
        CourseResponse course = teacherCourseMapper.findByTeacherIdAndCourseName(teacherId, request.getCourseName())
            .stream()
            .findFirst()
            .orElseThrow(() -> new BusinessException("未找到指定课程"));
        
        // 根据班级名称查找教学班
        TeachingClassResponse teachingClass = teacherCourseMapper.findByTeacherIdAndCourseIdAndClassName(
                teacherId, course.getCourseId(), request.getClassName())
            .stream()
            .findFirst()
            .orElseThrow(() -> new BusinessException("未找到指定班级"));
        
        // 验证教师是否有权限在该课程和班级发布作业
        validateTeacherPermission(teacherId, course.getCourseId(), teachingClass.getTeachingClassId());
        
        // 验证时间
        validateTime(request.getStartTime(), request.getDeadline());
        
        // 转换并保存作业基本信息
        TeacherHomework homework = new TeacherHomework();
        BeanUtils.copyProperties(request, homework);
        homework.setCourseId(course.getCourseId());
        homework.setTeachingClassId(teachingClass.getTeachingClassId());
        homework.setTeacherId(teacherId);
        teacherHomeworkMapper.insert(homework);
        
        // 处理附件上传
        if (attachment != null && !attachment.isEmpty()) {
            handleAttachmentUpload(homework.getHomeworkId(), attachment);
        }
        
        // 保存作业题目
        saveQuestions(homework.getHomeworkId(), request.getQuestions());
        
        // 分发作业给班级的所有学生
        distributeHomeworkToStudents(homework);
        
        return homework.getHomeworkId();
    }

    private void distributeHomeworkToStudents(TeacherHomework homework) {
        // 获取班级所有学生
        List<Long> studentIds = teachingClassMapper.findStudentIdsByClassId(homework.getTeachingClassId());
        if (studentIds.isEmpty()) {
            throw new BusinessException("该班级暂无学生");
        }

        // 获取课程信息
        String courseName = teacherCourseMapper.findCourseNameById(homework.getCourseId());
        String teacherName = teacherCourseMapper.findTeacherNameById(homework.getTeacherId());
        String semesterName = teacherCourseMapper.findSemesterNameById(homework.getSemesterId());

        // 为每个学生创建作业记录
        for (Long studentId : studentIds) {
            // 检查是否已存在该学生的作业记录
            HomeworkStudent existingHomework = homeworkStudentMapper.findByTeacherHomeworkIdAndStudentId(homework.getHomeworkId(), studentId);
            if (existingHomework != null) {
                // 如果已存在，则跳过该学生
                continue;
            }

            HomeworkStudent studentHomework = new HomeworkStudent();
            studentHomework.setTeacherHomeworkId(homework.getHomeworkId());
            studentHomework.setTitle(homework.getTitle());
            studentHomework.setPublisherName(teacherName);
            studentHomework.setCourseName(courseName);
            studentHomework.setStartTime(homework.getStartTime());
            studentHomework.setDeadline(homework.getDeadline());
            studentHomework.setStatus(0); // 0-未交
            studentHomework.setStudentId(studentId);
            studentHomework.setSemesterName(semesterName);
            
            try {
                homeworkStudentMapper.insert(studentHomework);
            } catch (Exception e) {
                // 如果插入失败，继续处理下一个学生
                continue;
            }
        }
    }

    @Override
    public List<CourseResponse> getTeacherCourses(String courseName) {
        Long teacherId = securityUtils.getCurrentUserId();
        return teacherCourseMapper.findByTeacherIdAndCourseName(teacherId, courseName != null ? courseName : "");
    }

    @Override
    public List<TeachingClassResponse> getTeachingClasses(Long courseId, String className) {
        Long teacherId = securityUtils.getCurrentUserId();
        return teacherCourseMapper.findByTeacherIdAndCourseIdAndClassName(teacherId, courseId, className != null ? className : "");
    }

    private void validateTeacherPermission(Long teacherId, Long courseId, Long teachingClassId) {
        boolean hasPermission = teacherCourseMapper.validateTeacherCourseClass(teacherId, courseId, teachingClassId);
        if (!hasPermission) {
            throw new BusinessException("您没有权限在该课程的该班级发布作业");
        }
    }

    private void validateTime(LocalDateTime startTime, LocalDateTime deadline) {
        if (startTime.isAfter(deadline)) {
            throw new BusinessException("开始时间不能晚于截止时间");
        }
        if (startTime.isBefore(LocalDateTime.now())) {
            throw new BusinessException("开始时间不能早于当前时间");
        }
    }

    private void handleAttachmentUpload(Long homeworkId, MultipartFile file) {
        try {
            // 创建上传目录
            String uploadDir = "/uploads/homework/" + LocalDateTime.now().getYear() + "/" + 
                             String.format("%02d", LocalDateTime.now().getMonthValue());
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String filename = UUID.randomUUID().toString() + extension;

            // 保存文件
            Path filePath = uploadPath.resolve(filename);
            Files.copy(file.getInputStream(), filePath);

            // 保存附件信息
            HomeworkAttachment attachment = new HomeworkAttachment();
            attachment.setHomeworkId(homeworkId);
            attachment.setFileName(originalFilename);
            attachment.setFilePath(uploadDir + "/" + filename);
            attachment.setFileSize(file.getSize());
            attachment.setFileType(file.getContentType());
            attachment.setUploadTime(LocalDateTime.now());
            
            homeworkAttachmentMapper.insert(attachment);
        } catch (IOException e) {
            throw new BusinessException("文件上传失败：" + e.getMessage());
        }
    }

    private void saveQuestions(Long homeworkId, List<HomeworkQuestionRequest> questionRequests) {
        if (questionRequests == null || questionRequests.isEmpty()) {
            throw new BusinessException("作业题目不能为空");
        }

        List<HomeworkQuestion> questions = questionRequests.stream().map(request -> {
            HomeworkQuestion question = new HomeworkQuestion();
            // 手动复制基本属性
            question.setHomeworkId(homeworkId);
            question.setQuestionType(request.getQuestionType());
            question.setQuestionContent(request.getQuestionContent());
            question.setAnswer(request.getAnswer());
            
            // 处理分数转换
            if (request.getScore() != null) {
                question.setScore(request.getScore().intValue());
            } else {
                throw new BusinessException("题目分数不能为空");
            }
            
            // 处理选项
            if (request.getOptions() != null) {
                List<HomeworkQuestion.QuestionOption> options = request.getOptions().stream()
                    .map(opt -> {
                        HomeworkQuestion.QuestionOption questionOption = new HomeworkQuestion.QuestionOption();
                        questionOption.setOptionLabel(opt.getOptionLabel());
                        questionOption.setOptionContent(opt.getOptionContent());
                        return questionOption;
                    })
                    .collect(Collectors.toList());
                question.setOptions(options);
            }
            
            return question;
        }).collect(Collectors.toList());

        questions.forEach(homeworkQuestionMapper::insert);
    }

    @Override
    public Page<HomeworkListResponse> getHomeworkList(HomeworkStatus status, String courseName, Integer pageNum, Integer pageSize) {
        // 获取当前教师ID
        Long teacherId = securityUtils.getCurrentUserId();
        
        // 1. 首先获取教师的课程列表
        List<TeacherCourse> teacherCourses = teacherCourseMapper.selectList(
            new LambdaQueryWrapper<TeacherCourse>()
                .eq(TeacherCourse::getTeacherId, teacherId)
                .eq(TeacherCourse::getStatus, "进行中")
        );
        List<Long> courseIds = teacherCourses.stream()
            .map(TeacherCourse::getCourseId)
            .collect(Collectors.toList());
            
        // 2. 如果指定了课程名称，先筛选课程
        if (StringUtils.hasText(courseName)) {
            List<Course> courses = courseMapper.selectList(
                new LambdaQueryWrapper<Course>()
                    .in(Course::getCourseId, courseIds)
                    .like(Course::getCourseName, courseName)
            );
            courseIds = courses.stream()
                .map(Course::getCourseId)
                .collect(Collectors.toList());
        }
        
        // 3. 构建作业查询条件
        LambdaQueryWrapper<TeacherHomework> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TeacherHomework::getTeacherId, teacherId)
                   .in(TeacherHomework::getCourseId, courseIds)
                   .eq(TeacherHomework::getStatus, 1); // 1-有效
        
        // 4. 执行分页查询
        Page<TeacherHomework> homeworkPage = teacherHomeworkMapper.selectPage(
            new Page<>(pageNum, pageSize),
            queryWrapper.orderByDesc(TeacherHomework::getCreateTime)
        );
        
        // 5. 获取作业提交统计信息
        List<Long> homeworkIds = homeworkPage.getRecords().stream()
            .map(TeacherHomework::getHomeworkId)
            .collect(Collectors.toList());
            
        Map<Long, Integer> submissionStats = getSubmissionStats(homeworkIds);
        Map<Long, Integer> gradedStats = getGradedStats(homeworkIds);
        
        // 6. 转换为响应对象
        Page<HomeworkListResponse> responsePage = new Page<>();
        BeanUtils.copyProperties(homeworkPage, responsePage, "records");
        
        // 7. 转换记录列表
        List<HomeworkListResponse> responseList = homeworkPage.getRecords().stream()
            .map(homework -> {
                HomeworkListResponse response = new HomeworkListResponse();
                BeanUtils.copyProperties(homework, response);
                
                // 设置提交统计信息
                Integer submittedCount = submissionStats.getOrDefault(homework.getHomeworkId(), 0);
                Integer gradedCount = gradedStats.getOrDefault(homework.getHomeworkId(), 0);
                
                response.setSubmittedCount(submittedCount);
                
                // 获取教学班信息
                TeachingClass teachingClass = teachingClassMapper.selectById(homework.getTeachingClassId());
                if (teachingClass != null) {
                    response.setTeachingClassId(teachingClass.getTeachingClassId());
                    response.setClassName(teachingClass.getClassName());
                    response.setGrade(teachingClass.getGrade().toString());
                    response.setTotalCount(teachingClass.getStudentCount());
                }
                
                // 获取课程信息
                Course course = courseMapper.selectById(homework.getCourseId());
                if (course != null) {
                    response.setCourseName(course.getCourseName());
                }
                
                // 设置作业状态
                if (submittedCount == 0) {
                    response.setStatus("未提交");
                } else if (gradedCount.equals(submittedCount)) {
                    response.setStatus("已批改");
                } else {
                    response.setStatus("部分批改");
                }
                
                return response;
            })
            .filter(response -> {
                if (status == null || status == HomeworkStatus.ALL) {
                    return true;
                }
                return switch (status) {
                    case SUBMITTED -> "已提交".equals(response.getStatus());
                    case UNSUBMITTED -> "未提交".equals(response.getStatus());
                    case GRADED -> "已批改".equals(response.getStatus());
                    case UNGRADED -> "部分批改".equals(response.getStatus());
                    default -> true;
                };
            })
            .collect(Collectors.toList());
        
        responsePage.setRecords(responseList);
        return responsePage;
    }
    
    /**
     * 获取作业提交统计信息
     */
    private Map<Long, Integer> getSubmissionStats(List<Long> homeworkIds) {
        if (homeworkIds.isEmpty()) {
            return Map.of();
        }
        
        return homeworkSubmissionMapper.selectList(
            new LambdaQueryWrapper<HomeworkSubmission>()
                .in(HomeworkSubmission::getHomeworkId, homeworkIds)
                .in(HomeworkSubmission::getSubmissionStatus, "submitted", "late", "accepted")
        ).stream().collect(
            Collectors.groupingBy(
                HomeworkSubmission::getHomeworkId,
                Collectors.collectingAndThen(Collectors.counting(), Long::intValue)
            )
        );
    }
    
    /**
     * 获取已批改作业统计信息
     */
    private Map<Long, Integer> getGradedStats(List<Long> homeworkIds) {
        if (homeworkIds.isEmpty()) {
            return Map.of();
        }
        
        return homeworkSubmissionMapper.selectList(
            new LambdaQueryWrapper<HomeworkSubmission>()
                .in(HomeworkSubmission::getHomeworkId, homeworkIds)
                .in(HomeworkSubmission::getSubmissionStatus, "accepted")
        ).stream().collect(
            Collectors.groupingBy(
                HomeworkSubmission::getHomeworkId,
                Collectors.collectingAndThen(Collectors.counting(), Long::intValue)
            )
        );
    }
    
    /**
     * 获取班级学生总数
     */
    private Integer getClassStudentCount(Long teachingClassId) {
        if (teachingClassId == null) {
            return 0;
        }
        TeachingClass teachingClass = teachingClassMapper.selectById(teachingClassId);
        return teachingClass != null ? teachingClass.getStudentCount() : 0;
    }

    /**
     * 计算学生作业得分详情
     * @param homeworkId 作业ID
     * @param studentId 学生ID
     * @return 作业得分详情，包含总分和每道题的得分
     */
    @Override
    public HomeworkScoreDetailResponse calculateHomeworkScore(Long homeworkId, Long studentId) {
        // 1. 获取作业的所有题目
        List<HomeworkQuestion> questions = homeworkQuestionMapper.selectList(
            new LambdaQueryWrapper<HomeworkQuestion>()
                .eq(HomeworkQuestion::getHomeworkId, homeworkId)
                .orderBy(true, true, HomeworkQuestion::getSortOrder)  // 按题号排序
        );

        // 2. 获取学生的简答题提交记录
        List<HomeworkSubmission> textSubmissions = homeworkSubmissionMapper.selectList(
            new LambdaQueryWrapper<HomeworkSubmission>()
                .eq(HomeworkSubmission::getHomeworkId, homeworkId)
                .eq(HomeworkSubmission::getStudentId, studentId)
        );

        // 3. 获取学生的选择题提交记录
        List<QuestionSubmission> choiceSubmissions = questionSubmissionMapper.selectList(
            new LambdaQueryWrapper<QuestionSubmission>()
                .eq(QuestionSubmission::getHomeworkId, homeworkId)
                .eq(QuestionSubmission::getStudentId, studentId)
        );

        // 4. 计算总分和构建响应对象
        HomeworkScoreDetailResponse response = new HomeworkScoreDetailResponse();
        response.setHomeworkId(homeworkId);
        response.setStudentId(studentId);

        double totalScore = 0.0;
        double maxPossibleScore = 0.0;
        List<HomeworkScoreDetailResponse.QuestionScoreDetail> questionScores = new ArrayList<>();

        for (HomeworkQuestion question : questions) {
            HomeworkScoreDetailResponse.QuestionScoreDetail detail = new HomeworkScoreDetailResponse.QuestionScoreDetail();
            detail.setQuestionId(question.getQuestionId());
            detail.setQuestionType(question.getQuestionType());
            detail.setQuestionContent(question.getQuestionContent());
            detail.setMaxScore(question.getScore().doubleValue());
            maxPossibleScore += question.getScore().doubleValue();

            if ("text".equals(question.getQuestionType())) {
                // 处理简答题
                Optional<HomeworkSubmission> submission = textSubmissions.stream()
                    .filter(s -> s.getQuestionId().equals(question.getQuestionId()))
                    .findFirst();

                if (submission.isPresent()) {
                    HomeworkSubmission sub = submission.get();
                    // 设置学生答案（文本内容和文件路径）
                    StringBuilder answer = new StringBuilder();
                    if (sub.getContentText() != null) {
                        answer.append(sub.getContentText());
                    }
                    if (sub.getFilePath() != null) {
                        if (answer.length() > 0) {
                            answer.append("\n");
                        }
                        answer.append("文件路径：").append(sub.getFilePath());
                    }
                    detail.setStudentAnswer(answer.toString());
                    
                    detail.setActualScore(sub.getScore() != null ? sub.getScore().doubleValue() : 0.0);
                    detail.setIsCorrect("accepted".equals(sub.getSubmissionStatus()));
                    if (sub.getScore() != null) {
                        totalScore += sub.getScore().doubleValue();
                    }
                } else {
                    detail.setStudentAnswer(null);
                    detail.setActualScore(0.0);
                    detail.setIsCorrect(false);
                }
            } else {
                // 处理选择题
                Optional<QuestionSubmission> submission = choiceSubmissions.stream()
                    .filter(s -> s.getQuestionId().equals(question.getQuestionId()))
                    .findFirst();

                if (submission.isPresent()) {
                    QuestionSubmission sub = submission.get();
                    detail.setStudentAnswer(sub.getAnswer());
                    detail.setActualScore(sub.getScore().doubleValue());
                    detail.setIsCorrect(sub.getIsCorrect());
                    totalScore += sub.getScore().doubleValue();
                } else {
                    detail.setStudentAnswer(null);
                    detail.setActualScore(0.0);
                    detail.setIsCorrect(false);
                }
            }

            questionScores.add(detail);
        }

        response.setTotalScore(totalScore);
        response.setMaxPossibleScore(maxPossibleScore);
        response.setScorePercentage(maxPossibleScore > 0 ? (totalScore / maxPossibleScore) * 100 : 0.0);
        response.setQuestionScores(questionScores);

        return response;
    }

    @Override
    @Transactional
    public HomeworkScoreDetailResponse gradeTextQuestion(Long homeworkId, Long studentId, Long questionId, BigDecimal score) {
        // 1. 验证分数范围
        if (score.compareTo(BigDecimal.ZERO) < 0 || score.compareTo(new BigDecimal("100")) > 0) {
            throw new BusinessException("分数必须在0-100之间");
        }

        // 2. 获取作业提交记录
        HomeworkSubmission submission = homeworkSubmissionMapper.selectOne(
            new LambdaQueryWrapper<HomeworkSubmission>()
                .eq(HomeworkSubmission::getHomeworkId, homeworkId)
                .eq(HomeworkSubmission::getStudentId, studentId)
                .eq(HomeworkSubmission::getQuestionId, questionId)
        );

        if (submission == null) {
            throw new BusinessException("未找到该学生的作业提交记录");
        }

        // 3. 更新分数和状态
        submission.setScore(score);
        submission.setSubmissionStatus("accepted");  // 使用正确的字段名
        submission.setTeacherId(securityUtils.getCurrentUserId());  // 记录批改教师ID
        submission.setUpdateTime(LocalDateTime.now());
        
        homeworkSubmissionMapper.updateById(submission);

        // 4. 返回更新后的作业得分详情
        return calculateHomeworkScore(homeworkId, studentId);
    }
} 